package model.datareader;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import model.WebHistoryDataException;


/**
 * Factory class to generate DataReaders.
 * @author Niel Lebeck
 *
 */
public final class DataReaderFactory {

    private DataReaderFactory () {

    }

    /**
     * Create a new DataReader with the given file type using
     * reflection.
     * @param fileType the file ending of the file to be read
     * @throws WebHistoryDataException errors in reflection
     * @return new DataReader of the right kind
     */
    public static DataReader createDataReader (String fileType) throws WebHistoryDataException {
        ResourceBundle myResources = ResourceBundle.getBundle("resources.WebHistory");
        DataReader result = null;

        if (fileType == null) {
            throw new WebHistoryDataException("unsupported file type");
        }
        
        //use reflection to instantiate the Visualization
        String className = null;
        try {
            className = myResources.getString(fileType);
        }
        catch (MissingResourceException e) {
            throw new WebHistoryDataException(
                    "unsupported file type: reader class not specified in properties file");
        }
        Constructor<?> c = getDataReaderConstructor(className);
        try {
            result = (DataReader)c.newInstance();
        }
        catch (IllegalArgumentException e) {
            throw new WebHistoryDataException("illegal number of arguments for constructor");
        }
        catch (InstantiationException e) {
            throw new WebHistoryDataException("illegal instantiation");
        }
        catch (IllegalAccessException e) {
            throw new WebHistoryDataException("illegal access");
        }
        catch (InvocationTargetException e) {
            throw new WebHistoryDataException("illegal invocation target using command");
        }
        return result;
    }



    private static Constructor<?> getDataReaderConstructor(String className)
        throws WebHistoryDataException {
        Constructor<?>[] constructList = null;

        try {
            constructList = Class.forName(className).getDeclaredConstructors();
        }
        catch (SecurityException e) {
            throw new WebHistoryDataException("security exception");
        }
        catch (ClassNotFoundException e) {
            throw new WebHistoryDataException("class not found");
        }

        for (Constructor<?> c : constructList) {
            if (c.getParameterTypes().length == 0) {
                return c;
            }
        }
        return null;
    }

}
